/**
 * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springblade.modules.bank.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.cache.MapCache;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;
import javax.validation.Valid;

import lombok.extern.slf4j.Slf4j;
import org.springblade.common.tool.MyStringUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.SecureUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.bank.entity.*;
import org.springblade.modules.bank.excel.TmCustomerExcel;
import org.springblade.modules.bank.excel.TmVisitTaskExcel;
import org.springblade.modules.bank.service.*;
import org.springblade.modules.bank.util.AESUtil;
import org.springblade.modules.bank.util.BusFileUtil;
import org.springblade.modules.bank.vo.TmCustomerTagVO;
import org.springblade.modules.system.entity.Dept;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IDeptService;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestParam;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springblade.modules.bank.vo.TmCustomerVO;
import org.springblade.core.boot.ctrl.BladeController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static org.springblade.modules.bank.constant.BankConstant.EX1_TYPE_BUSINESS;

/**
 * 客户信息 控制器
 *
 * @author Blade
 * @since 2022-07-08
 */
@RestController
@AllArgsConstructor
@RequestMapping("/tmcustomer")
@Api(value = "客户信息", tags = "客户信息接口")
@Slf4j
public class TmCustomerController extends BladeController {

	private ITmCustomerService tmCustomerService;

	private ITmCustomerLogService tmCustomerLogService;

	private ITmVisitTaskCustomerService iTmVisitTaskCustomerService;

	private IUserService userService;

	private IDeptService deptService;

	private ITmCustomerTagService tmCustomerTagService;

	private ITmExcelImportLogService tmExcelImportLogService;

	private Environment environment;

	private ITmCustomerCallRecordService tmCustomerCallRecordService;

	private ITmVisitTaskService tmVisitTaskService;

	private ITmVisitTaskCustomerService tmVisitTaskCustomerService;
	/**
	 * 详情
	 */
	@GetMapping("/detail")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入tmCustomer")
	public R<TmCustomer> detail(TmCustomer tmCustomer) {
		TmCustomer detail = tmCustomerService.getOne(Condition.getQueryWrapper(tmCustomer));
		try {
			if (MyStringUtil.isNotEmpty(detail.getCustomerName())){
				detail.setCustomerName(AESUtil.decrypt(detail.getCustomerName(),BankConstants.KEY));
			}
			if (MyStringUtil.isNotEmpty(detail.getCustomerTel())){
				detail.setCustomerTel(AESUtil.decrypt(detail.getCustomerTel(),BankConstants.KEY));
			}
			if (MyStringUtil.isNotEmpty(detail.getCustomerTelBack())){
				detail.setCustomerTelBack(AESUtil.decrypt(detail.getCustomerTelBack(),BankConstants.KEY));
			}
		} catch (Exception e) {
			log.warn("Exception",e);
		}
		return R.data(detail);
	}

	/**
	 * 详情
	 */
	@GetMapping("/getCustomer")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "传入tmCustomer")
	public R<TmCustomer> getCustomer(TmCustomer tmCustomer) throws Exception {
		if(MyStringUtil.isNotEmpty(tmCustomer.getCustomerTel())){
			tmCustomer.setCustomerTel(AESUtil.encrypt(tmCustomer.getCustomerTel(),BankConstants.KEY));
		}

		List<TmCustomer> tmCustomerList = tmCustomerService.list(Condition.getQueryWrapper(tmCustomer).orderByDesc("id"));
		if (tmCustomerList.size()>0){
			TmCustomer retTmCustomer = tmCustomerList.get(0);
			if(MyStringUtil.isNotEmpty(retTmCustomer.getCustomerName())){
				retTmCustomer.setCustomerName(AESUtil.decrypt(retTmCustomer.getCustomerName(),BankConstants.KEY));
			}
			if(MyStringUtil.isNotEmpty(retTmCustomer.getCustomerTel())){
				retTmCustomer.setCustomerTel(AESUtil.decrypt(retTmCustomer.getCustomerTel(),BankConstants.KEY));
			}
			return R.data(retTmCustomer);
		}else{
			return R.data(new TmCustomer());
		}
	}

	/**
	 * 分页 客户信息
	 */
	@GetMapping("/list")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入tmCustomer")
	public R<IPage<TmCustomer>> list(TmCustomerVO tmCustomerVO, Query query) throws Exception {
		TmCustomer tmCustomerTemp = tmCustomerVO;
		String productTage = tmCustomerVO.getProductTag();
		tmCustomerVO.setProductTag(null);
		String customerName = tmCustomerVO.getCustomerName();
		tmCustomerVO.setCustomerName(null);
		String customerTel = tmCustomerVO.getCustomerTel();
		tmCustomerVO.setCustomerTel(null);
		LambdaQueryWrapper<TmCustomer> lambdaQueryWrapper = Condition.getQueryWrapper(tmCustomerTemp).lambda();
		if(MyStringUtil.isNotEmpty(productTage)){
			lambdaQueryWrapper.like(TmCustomer::getProductTag,productTage);
		}
		if(MyStringUtil.isNotEmpty(customerName)){
			customerName = AESUtil.encrypt(customerName,BankConstants.KEY);
			lambdaQueryWrapper.eq(TmCustomer::getCustomerName,customerName);
		}
		if(MyStringUtil.isNotEmpty(customerTel)){
			customerTel = AESUtil.encrypt(customerTel,BankConstants.KEY);
			lambdaQueryWrapper.eq(TmCustomer::getCustomerTel,customerTel);
		}
		if (tmCustomerVO.getDataPermission()!=null){
			if (tmCustomerVO.getDataPermission()==1){}
			else if(tmCustomerVO.getDataPermission()==2){
				List<Dept> deptList = deptService.list(new LambdaQueryWrapper<Dept>().eq(Dept::getParentId,tmCustomerVO.getQueryParentDeptId()));
				List<Long> deptIdList = deptList.stream().map(item->item.getId()).collect(Collectors.toList());
				if (deptIdList.size()==0){
					return R.data(null);
				}
				lambdaQueryWrapper.in(TmCustomer::getDeptId,deptIdList);
			}else if(tmCustomerVO.getDataPermission()==3){
				lambdaQueryWrapper.eq(TmCustomer::getDeptId,tmCustomerVO.getQueryDeptId());
			}
		}
		lambdaQueryWrapper.orderByAsc(TmCustomer::getCustomerCode);
		IPage<TmCustomer> pages = tmCustomerService.page(Condition.getPage(query), lambdaQueryWrapper);
		pages.getRecords().forEach(item->{
			try {
				if (MyStringUtil.isNotEmpty(item.getCustomerName())){
					item.setCustomerName(AESUtil.decrypt(item.getCustomerName(),BankConstants.KEY));
				}
				if (MyStringUtil.isNotEmpty(item.getCustomerTel())){
					item.setCustomerTel(AESUtil.decrypt(item.getCustomerTel(),BankConstants.KEY));
				}
				if (MyStringUtil.isNotEmpty(item.getCustomerTelBack())){
					item.setCustomerTelBack(AESUtil.decrypt(item.getCustomerTelBack(),BankConstants.KEY));
				}
			} catch (Exception e) {
				log.warn("Exception",e);
			}
		});
		return R.data(pages);
	}

	/**
	 * 自定义分页 客户信息
	 */
	@GetMapping("/page")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "分页", notes = "传入tmCustomer")
	public R<IPage<TmCustomerVO>> page(TmCustomerVO tmCustomer, Query query) {
		IPage<TmCustomerVO> pages = tmCustomerService.selectTmCustomerPage(Condition.getPage(query), tmCustomer);
		return R.data(pages);
	}

	/**
	 * 新增 客户信息
	 */
	@PostMapping("/save")
	@ApiOperationSupport(order = 4)
	@ApiOperation(value = "新增", notes = "传入tmCustomer")
	public R save(@Valid @RequestBody TmCustomer tmCustomer) {
		return R.status(tmCustomerService.save(tmCustomer));
	}

	/**
	 * 修改 客户信息
	 */
	@PostMapping("/update")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入tmCustomer")
	public R update(@Valid @RequestBody TmCustomer tmCustomer) {
		return R.status(tmCustomerService.updateById(tmCustomer));
	}

	/**
	 * 修改 客户信息
	 */
	@PostMapping("/updatePortrait")
	@ApiOperationSupport(order = 5)
	@ApiOperation(value = "修改", notes = "传入tmCustomer")
	public R updatePortrait(@Valid @RequestBody TmCustomer tmCustomer) {
		TmCustomer tmCustomerTemp = tmCustomerService.getOne(new LambdaQueryWrapper<TmCustomer>().eq(TmCustomer::getCustomerCode,tmCustomer.getCustomerCode()));
		tmCustomerTemp.setPortrait(tmCustomer.getPortrait());
		return R.status(tmCustomerService.updateById(tmCustomerTemp));
	}

	/**
	 * 新增或修改 客户信息
	 */
	@PostMapping("/submit")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入tmCustomer")
	@Transactional(rollbackFor = Exception.class)
	public R submit(@Valid @RequestBody TmCustomerVO tmCustomer) throws Exception {
		LambdaQueryWrapper<TmCustomer> lambdaQueryWrapper = new LambdaQueryWrapper();
		lambdaQueryWrapper.eq(TmCustomer::getCustomerCode,tmCustomer.getCustomerCode());
		TmCustomer existCustomer = tmCustomerService.getOne(lambdaQueryWrapper);

		if (existCustomer!=null&&tmCustomer.getId()==null){
			throw new RuntimeException("新增失败，客户编号【"+tmCustomer.getCustomerCode()+"】已经存在，保存失败!");
		}

//		//批量更新任务中的性别
//		LambdaQueryWrapper<TmVisitTaskCustomer> tmVisitTaskCustomerLambdaQueryWrapper = new LambdaQueryWrapper<>();
//		tmVisitTaskCustomerLambdaQueryWrapper.eq(TmVisitTaskCustomer::getCustomerCode,tmCustomer.getCustomerCode());
//		List<TmVisitTaskCustomer> tmVisitTaskCustomerList = iTmVisitTaskCustomerService.list(tmVisitTaskCustomerLambdaQueryWrapper);
//		tmVisitTaskCustomerList.forEach(item->{
//			item.setSex(tmCustomer.getSex());
//		});
//		iTmVisitTaskCustomerService.saveOrUpdateBatch(tmVisitTaskCustomerList);

		if(MyStringUtil.isNotEmpty(tmCustomer.getCustomerTelPre())){
			User user = userService.getOne(new QueryWrapper<User>().lambda().eq(User::getCode, tmCustomer.getCustMgr()));
			user.setCustomerTelPre(tmCustomer.getCustomerTelPre());
			userService.saveOrUpdate(user);
		}

		String telAES = AESUtil.encrypt(tmCustomer.getCustomerTel(),BankConstants.KEY);

		List custList =  tmCustomerService.list(new LambdaQueryWrapper<TmCustomer>().eq(TmCustomer::getCustomerTel,telAES)
				.ne(TmCustomer::getCustomerCode,tmCustomer.getCustomerCode()));
		if (custList.size()>0){
			throw new RuntimeException("电话号码已经存在，当前电话号码的客户编号为："+tmCustomer.getCustomerCode()+"，保存失败!");
		}

		TmCustomer tmCustomerOri =  tmCustomerService.getOne(new LambdaQueryWrapper<TmCustomer>().eq(TmCustomer::getCustomerCode,tmCustomer.getCustomerCode()));
		if (tmCustomerOri!=null&&!telAES.equals(tmCustomerOri.getCustomerTel())){
			if (tmCustomerOri.getTelModifyTime()!=null&&tmCustomerOri.getTelModifyTime()>2){
				throw new RuntimeException("电话号码已经修改3次，系统已不允许修改，保存失败!");
			}else{
				tmCustomer.setTelModifyTime((tmCustomerOri.getTelModifyTime()==null?0:tmCustomerOri.getTelModifyTime())+1);
			}
		}

		//AES加密 客户姓名 客户电话
		tmCustomer.setCustomerName(AESUtil.encrypt(tmCustomer.getCustomerName(),BankConstants.KEY));
		tmCustomer.setCustomerTel(telAES);
		if(MyStringUtil.isNotEmpty(tmCustomer.getCustomerTelBack())){
			tmCustomer.setCustomerTelBack(AESUtil.encrypt(tmCustomer.getCustomerTelBack(),BankConstants.KEY));
		}
		if(existCustomer==null){
			tmCustomer.setDelFlag(0);
			tmCustomerService.saveOrUpdate(tmCustomer);
			return R.data(tmCustomer);
		}else{
			BeanUtil.copyProperties(tmCustomer,existCustomer,"id");
			tmCustomerService.saveOrUpdate(existCustomer);
			return R.data(existCustomer);
		}
	}

	/**
	 * 新增或修改 客户信息
	 */
	@PostMapping("/updateCustomerTelPre")
	@ApiOperationSupport(order = 6)
	@ApiOperation(value = "新增或修改", notes = "传入tmCustomer")
	public R updateCustomerTelPre(@Valid @RequestBody TmCustomerVO tmCustomer) {
		User user = userService.getOne(new QueryWrapper<User>().lambda().eq(User::getCode, tmCustomer.getCustMgr()));
		user.setCustomerTelPre(tmCustomer.getCustomerTelPre());
		userService.saveOrUpdate(user);
		return R.data(user);
	}


	/**
	 * 删除 客户信息
	 * 仅修改del_flag状态为1 废弃，不物理删除
	 */
	@PostMapping("/remove")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		List<TmCustomer> tmCustomerList = tmCustomerService.listByIds(Func.toLongList(ids));
		if(tmCustomerList.size()>0){
			tmCustomerList.forEach(item-> item.setDelFlag(1));
			boolean ret = tmCustomerService.updateBatchById(tmCustomerList);
			return R.status(ret);
		}else{
			return R.status(false);
		}
	}

	/**
	 * 启用 客户信息
	 * 仅修改del_flag状态为0 启用
	 */
	@PostMapping("/enable")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R enable(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
		List<TmCustomer> tmCustomerList = tmCustomerService.listByIds(Func.toLongList(ids));
		if(tmCustomerList.size()>0){
			tmCustomerList.forEach(item-> item.setDelFlag(0));
			boolean ret = tmCustomerService.updateBatchById(tmCustomerList);
			return R.status(ret);
		}else{
			return R.status(false);
		}
	}

	/**
	 * 客户导入
	 */
	@PostMapping("/customerImport")
	@ApiOperationSupport(order = 12)
	@ApiOperation(value = "任务导入", notes = "传入excel")
	@Transactional(rollbackFor = Exception.class)
	public R customerImport(MultipartFile file) {
		TmExcelImportLog tmExcelImportLog = new TmExcelImportLog();
		tmExcelImportLog.setImportType("客户信息导入");
		tmExcelImportLog.setFlag("导入失败");
		BusFileUtil.uploadFile(tmExcelImportLog,file,environment.getProperty("recordFilePath"));
//		tmExcelImportLogService.save(tmExcelImportLog);

		String filename = file.getOriginalFilename();
		if (StringUtils.isEmpty(filename)) {
			throw new RuntimeException("请上传文件!");
		}
		if ((!StringUtils.endsWithIgnoreCase(filename, ".xls") && !StringUtils.endsWithIgnoreCase(filename, ".xlsx"))) {
			throw new RuntimeException("请上传正确的excel文件!");
		}
		log.info("Excel read start:"+System.currentTimeMillis());
		List<TmCustomerExcel> list = new ArrayList<>(); //定义excel表格数据
		AnalysisEventListener<TmCustomerExcel> analysisEventListener = new AnalysisEventListener<TmCustomerExcel>() {
			// 这个每一条数据解析都会来调用
			@Override
			public void invoke(TmCustomerExcel data, AnalysisContext context) {
				list.add(data);
				// TODO 这里也可以对数据进行操作
			}

			// 所有数据解析完成了都会来调用
			@Override
			public void doAfterAllAnalysed(AnalysisContext context) {
				// TODO 这里也可以对数据进行操作
			}
		};
		InputStream inputStream;
		try {
			inputStream = file.getInputStream();
		} catch (IOException e) {
			return null;
		}
		EasyExcel.read(inputStream, TmCustomerExcel.class, analysisEventListener).sheet().doRead();
		log.info("Excel read end:"+System.currentTimeMillis());
		log.info("Excel data length:"+list.size());

		Map<String, User> custMgrMap = new HashMap<>();
		Map<String, Dept> deptMap = new HashMap<>();
		Map<String, String> dept_taskMap = new HashMap<>();
		Map<String, String> customerMap = new HashMap<>();
		Map<String, String> customerPhoneMap = new HashMap<>();
		Map<String, TmCustomerExcel> mainMap = new HashMap<>();
		List<TmVisitTask> addTask = new ArrayList<>();
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
		for (TmCustomerExcel tmCustomerExcel : list) {
			if(null == tmCustomerExcel.getDeptName() || "".equals(tmCustomerExcel.getDeptName()) )
				return R.fail("部门不能为空！请检查");
			if(null == tmCustomerExcel.getCustMgr() || "".equals(tmCustomerExcel.getCustMgr()) )
				return R.fail("客户经理编号不能为空！请检查");
			if(null == tmCustomerExcel.getCustomerCode() || "".equals(tmCustomerExcel.getCustomerCode()) )
				return R.fail("客户编号不能为空！请检查");
//            if(null == tmVisitTaskExcel.getSex() || "".equals(tmVisitTaskExcel.getSex()) )
//                return R.fail("性别不能为空！请检查");
			// 判断客户经理是否存在
			if (!custMgrMap.containsKey(tmCustomerExcel.getCustMgr())) {
				User user = userService.getOne(new QueryWrapper<User>().lambda().eq(User::getCode, tmCustomerExcel.getCustMgr()));
				if (null == user) {
					return R.fail("客户经理编码" + tmCustomerExcel.getCustMgr() + "不存在！请检查");
				} else {
					custMgrMap.put(tmCustomerExcel.getCustMgr(), user);
				}
			}
			// 判断部门是否存在
			if (!deptMap.containsKey(tmCustomerExcel.getDeptName())) {
				List<Dept> deptList = deptService.list(new QueryWrapper<Dept>().lambda().eq(Dept::getDeptName, tmCustomerExcel.getDeptName()));
				if (deptList.size() > 0) {
					deptMap.put(deptList.get(0).getDeptName(), deptList.get(0));
				} else {
					return R.fail("部门" + tmCustomerExcel.getDeptName() + "不存在！请检查");
				}
			}
			// 判断客户编码是否重复
			if (!customerMap.containsKey(tmCustomerExcel.getCustomerCode())) {
				customerMap.put(tmCustomerExcel.getCustomerCode(), tmCustomerExcel.getCustomerCode());
			} else {
				return R.fail("客户编码" + tmCustomerExcel.getCustomerCode() + "重复！请检查");
			}
		};
		for (TmCustomerExcel excelRow : list) {
			// 判断客户经理是否存在对应部门
			User user = custMgrMap.get(excelRow.getCustMgr());
			Dept dept = deptMap.get(excelRow.getDeptName());
			if (!user.getDeptId().equals(dept.getId().toString())) {
				return R.fail(dept.getDeptName() + "不存在客户经理" + user.getCode() + "_" + user.getName() + "！请检查");
			}
		}

		//TODO 导入客户信息表 调整管户关系
		BladeUser bladeUser = SecureUtil.getUser();
		//新增
		List<TmCustomer> newTmCustomerList = new ArrayList<>();
		List<TmCustomer> updateTmCustomerList = new ArrayList<>();
		//记录户管关系
		List<TmCustomerLog> tmCustomerLogList = new ArrayList<>();
		for (TmCustomerExcel customer : list) {
			long count = tmCustomerService.count(new QueryWrapper<TmCustomer>().lambda()
					.eq(TmCustomer::getCustomerCode, customer.getCustomerCode()));
			Dept dept = deptService.getOne(new LambdaQueryWrapper<Dept>().eq(Dept::getDeptName,customer.getDeptName()));
			User custMgr = userService.getOne(new QueryWrapper<User>().lambda().eq(User::getCode, customer.getCustMgr()));
			if (0 == count) {
				TmCustomer tmCustomer = new TmCustomer();
				tmCustomer.setCustomerCode(customer.getCustomerCode());
				tmCustomer.setCustMgr(customer.getCustMgr());
				tmCustomer.setCustMgrName(custMgr.getRealName());
				tmCustomer.setDeptId(dept.getId().toString());
				tmCustomer.setDeptName(customer.getDeptName());
				tmCustomer.setCustOrigin("2");
				tmCustomer.setDelFlag(0);//启用
				newTmCustomerList.add(tmCustomer);
				tmCustomerLogList.add(buildCustomerrLog(dept,tmCustomer,"新增"));
			}else {
				TmCustomer tmCustomer = tmCustomerService.getOne(new LambdaQueryWrapper<TmCustomer>().eq(TmCustomer::getCustomerCode,customer.getCustomerCode()));
				if (!tmCustomer.getDeptId().equals(dept.getId().toString())||!tmCustomer.getCustMgr().equals(customer.getCustMgr())){
					TmCustomerLog tmCustomerLog = new TmCustomerLog();
					tmCustomerLog.setCustomerCode(tmCustomer.getCustomerCode());
					tmCustomerLog.setCustomerName(tmCustomer.getCustomerName());
					//管户关系变更记录 原记录
					tmCustomerLog.setOriSubBranchCode(tmCustomer.getDeptId());
					tmCustomerLog.setOriSubBranchName(tmCustomer.getDeptName());
					tmCustomerLog.setOriCustMgr(tmCustomer.getCustMgr());
					tmCustomerLog.setOriCustMgrName(tmCustomer.getCustMgrName());
					//客户经理变更
					tmCustomer.setDeptId(dept.getId().toString());
					tmCustomer.setDeptName(dept.getDeptName());
					tmCustomer.setCustMgr(customer.getCustMgr());
					tmCustomer.setCustMgrName(custMgr.getRealName());
					//管户关系变更记录 修改记录
					tmCustomerLog.setSubBranchCode(dept.getId().toString());
					tmCustomerLog.setSubBranchName(dept.getDeptName());
					tmCustomerLog.setCustMgr(tmCustomer.getCustMgr());
					tmCustomerLog.setCustMgrName(tmCustomer.getCustMgrName());
					tmCustomerLog.setOperateDesc("修改");
					tmCustomerLogList.add(tmCustomerLog);
				}
				tmCustomer.setDelFlag(0);//刷新为启用
				updateTmCustomerList.add(tmCustomer);
			}
		}
		//新增导入
		tmCustomerService.saveBatch(newTmCustomerList);
		tmCustomerService.updateBatchById(updateTmCustomerList);
		//管户关系新增记录
		tmCustomerLogService.saveBatch(tmCustomerLogList);

		tmExcelImportLog.setCompleteTime(LocalDateTime.now());
		tmExcelImportLog.setFlag("导入成功");
//		tmExcelImportLogService.updateById(tmExcelImportLog);
		return R.success("导入成功");
	}

	private TmCustomerLog buildCustomerrLog(Dept dept,TmCustomer tmCustomer,String operateDesc){
		TmCustomerLog tmCustomerLog = new TmCustomerLog();
		tmCustomerLog.setSubBranchCode(dept.getId().toString());
		tmCustomerLog.setSubBranchName(dept.getDeptName());
		tmCustomerLog.setCustomerCode(tmCustomer.getCustomerCode());
		tmCustomerLog.setCustomerName(tmCustomer.getCustomerName());
		tmCustomerLog.setCustMgr(tmCustomer.getCustMgr());
		tmCustomerLog.setCustMgrName(tmCustomer.getCustMgrName());
		tmCustomerLog.setOperateDesc(operateDesc);
		return tmCustomerLog;
	}

	/**
	 * 客户导入
	 * 导入更多数据，以十万计
	 */
	@PostMapping("/customerImportMoreData")
	@ApiOperationSupport(order = 12)
	@ApiOperation(value = "任务导入", notes = "传入excel")
	@Transactional(rollbackFor = Exception.class)
	public R customerImportMoreData(MultipartFile file) throws Exception {
		tmCustomerCallRecordService.deleteBySql("delete from tm_import_customer_temp");

		TmExcelImportLog tmExcelImportLog = new TmExcelImportLog();
		tmExcelImportLog.setImportType("客户信息导入");
		tmExcelImportLog.setFlag("导入失败");
		BusFileUtil.uploadFile(tmExcelImportLog, file, environment.getProperty("recordFilePath"));
		tmExcelImportLogService.save(tmExcelImportLog);

		String filename = file.getOriginalFilename();
		if (StringUtils.isEmpty(filename)) {
			throw new RuntimeException("请上传文件!");
		}
		if ((!StringUtils.endsWithIgnoreCase(filename, ".xls") && !StringUtils.endsWithIgnoreCase(filename, ".xlsx"))) {
			throw new RuntimeException("请上传正确的excel文件!");
		}
		List<TmCustomerExcel> list = new ArrayList<>(); //定义excel表格数据
		AnalysisEventListener<TmCustomerExcel> analysisEventListener = new AnalysisEventListener<TmCustomerExcel>() {
			@Override
			public void invoke(TmCustomerExcel data, AnalysisContext context) {
				list.add(data);
			}
			@Override
			public void doAfterAllAnalysed(AnalysisContext context) {
			}
		};
		InputStream inputStream;
		try {
			inputStream = file.getInputStream();
		} catch (IOException e) {
			return null;
		}

		Map<String,Object> logInfo = new HashMap<>();

		logInfo.put("Excel read start:",System.currentTimeMillis());
		EasyExcel.read(inputStream, TmCustomerExcel.class, analysisEventListener).sheet().doRead();
		logInfo.put("Excel read end:",System.currentTimeMillis());

		if (list.size()>0){
			Map<String, User> custMgrMap = new HashMap<>();
			Map<String, Dept> deptMap = new HashMap<>();
			Map<String, String> customerMap = new HashMap<>();
			for (TmCustomerExcel tmCustomerExcel : list) {
				if(null == tmCustomerExcel.getDeptName() || "".equals(tmCustomerExcel.getDeptName()) )
					return R.fail("网点名称不能为空！请检查");
				if(null == tmCustomerExcel.getCustMgr() || "".equals(tmCustomerExcel.getCustMgr()) )
					return R.fail("人员编号不能为空！请检查");
				if(null == tmCustomerExcel.getCustomerCode() || "".equals(tmCustomerExcel.getCustomerCode()) )
					return R.fail("客户编号不能为空！请检查");
				// 判断客户经理是否存在
				if (!custMgrMap.containsKey(tmCustomerExcel.getCustMgr())) {
					User user = userService.getOne(new QueryWrapper<User>().lambda().eq(User::getCode, tmCustomerExcel.getCustMgr()));
					if (null == user) {
						return R.fail("客户经理编码" + tmCustomerExcel.getCustMgr() + "不存在！请检查");
					} else {
						custMgrMap.put(tmCustomerExcel.getCustMgr(), user);
					}
				}
				// 判断部门是否存在
				if (!deptMap.containsKey(tmCustomerExcel.getDeptName())) {
					List<Dept> deptList = deptService.list(new QueryWrapper<Dept>().lambda().eq(Dept::getDeptName, tmCustomerExcel.getDeptName()));
					if (deptList.size() > 0) {
						deptMap.put(deptList.get(0).getDeptName(), deptList.get(0));
					} else {
						return R.fail("部门" + tmCustomerExcel.getDeptName() + "不存在！请检查");
					}
				}
				// 判断客户编码是否重复
				if (!customerMap.containsKey(tmCustomerExcel.getCustomerCode())) {
					customerMap.put(tmCustomerExcel.getCustomerCode(), tmCustomerExcel.getCustomerCode());
				} else {
					return R.fail("客户编码" + tmCustomerExcel.getCustomerCode() + "重复！请检查");
				}
			}
			for (TmCustomerExcel excelRow : list) {
				// 判断客户经理是否存在对应部门
				User user = custMgrMap.get(excelRow.getCustMgr());
				Dept dept = deptMap.get(excelRow.getDeptName());
				if (!user.getDeptId().equals(dept.getId().toString())) {
					return R.fail(dept.getDeptName() + "不存在客户经理" + user.getCode() + "_" + user.getName() + "！请检查");
				}

				if(MyStringUtil.isNotEmpty(excelRow.getCustomerTel())){
					excelRow.setCustomerTel(AESUtil.encrypt(excelRow.getCustomerTel(),BankConstants.KEY));
				}
				if(MyStringUtil.isNotEmpty(excelRow.getCustomerName())){
					excelRow.setCustomerName(AESUtil.encrypt(excelRow.getCustomerName(),BankConstants.KEY));
				}
				if (MyStringUtil.isNotEmpty(excelRow.getSex())){
					if ("男".equals(excelRow.getSex())){
						excelRow.setSex("1");
					}else if("女".equals(excelRow.getSex())){
						excelRow.setSex("2");
					}else{
						excelRow.setSex(null);
					}
				}

			}

			tmCustomerService.addCustomerTempList(list);
		}

		logInfo.put("insert start:",System.currentTimeMillis());
		List<TmCustomer> newCustomerList = tmCustomerService.getNewCustomerList();
		if (newCustomerList.size()>0){
			newCustomerList.forEach(item->{
				item.setId(IdWorker.getId());
			});
			tmCustomerService.addCustomerList(newCustomerList);
		}
		logInfo.put("insert end:",System.currentTimeMillis());

		String updateMgrSql = "update tm_customer a \n" +
				"left join tm_import_customer_temp b \n" +
				"on a.customer_code=b.cust_code\n" +
				"left join blade_user c \n" +
				"on b.cust_mgr=c.`code`\n" +
				"set a.cust_mgr=b.cust_mgr,a.cust_mgr_name=c.`name`,a.update_time=sysdate() \n" +
				",a.customer_tel=(case when b.customer_tel is not null  and  b.customer_tel<>'' then b.customer_tel \n" +
				"                 else  a.customer_tel end)" +
				",a.customer_name=(case when b.customer_name is not null and  b.customer_name<>'' then b.customer_name else  a.customer_name end)" +
				",a.sex=(case when b.sex is not null  and  b.sex<>'' then b.sex else  a.sex end) \n"+
				"where a.customer_code=b.cust_code";
		logInfo.put("update start:",System.currentTimeMillis());
		tmCustomerCallRecordService.updateBySql(updateMgrSql);
		logInfo.put("update end:",System.currentTimeMillis());

		log.info("logInfo:====================="+logInfo.toString());

		tmExcelImportLog.setCompleteTime(LocalDateTime.now());
		tmExcelImportLog.setFlag("导入成功");
		tmExcelImportLogService.updateById(tmExcelImportLog);
		return R.success("导入成功");
	}

	/**
	 * 删除 客户信息
	 * 仅修改del_flag状态为1 废弃，不物理删除
	 */
	@PostMapping("/changeCustMgr")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R changeCustMgr(@ApiParam(value = "主键集合", required = true) @RequestParam String ids,String code) {
		List<TmCustomer> tmCustomerList = tmCustomerService.listByIds(Func.toLongList(ids));
		User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getCode,code));
		//记录户管关系
		List<TmCustomerLog> tmCustomerLogList = new ArrayList<>();
		if(tmCustomerList.size()>0&&user!=null){
			Dept dept = deptService.getOne(new LambdaQueryWrapper<Dept>().eq(Dept::getId,user.getDeptId()));
			tmCustomerList.forEach(item->{
				String oriCustMgr = item.getCustMgr();
				String oriCustMgrName = item.getCustMgrName();
				item.setCustMgr(user.getCode());
				item.setCustMgrName(user.getName());
				TmCustomerLog tmCustomerLog = buildCustomerrLog(dept,item,"调整客户经理");
				tmCustomerLog.setOriCustMgr(oriCustMgr);
				tmCustomerLog.setOriCustMgrName(oriCustMgrName);
				tmCustomerLog.setOriSubBranchCode(tmCustomerLog.getSubBranchCode());
				tmCustomerLog.setOriSubBranchName(tmCustomerLog.getSubBranchName());
				tmCustomerLogList.add(tmCustomerLog);
			});
			boolean ret = tmCustomerService.updateBatchById(tmCustomerList);
			//管户关系日志记录
			tmCustomerLogService.saveBatch(tmCustomerLogList);
			return R.status(ret);
		}else{
			return R.status(false);
		}
	}

	/**
	 * 删除 客户信息
	 * 仅修改del_flag状态为1 废弃，不物理删除
	 */
	@PostMapping("/changeDept")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	public R changeDept(@ApiParam(value = "主键集合", required = true) @RequestParam String ids,Long deptId) {
		List<TmCustomer> tmCustomerList = tmCustomerService.listByIds(Func.toLongList(ids));
		Dept dept = deptService.getOne(new LambdaQueryWrapper<Dept>().eq(Dept::getId,deptId));
		//记录户管关系
		List<TmCustomerLog> tmCustomerLogList = new ArrayList<>();
		if(tmCustomerList.size()>0&&dept!=null){
			tmCustomerList.forEach(item->{
				item.setDeptId(dept.getId().toString());
				item.setDeptName(dept.getDeptName());
				item.setCustMgr("");
				item.setCustMgrName("");
				tmCustomerLogList.add(buildCustomerrLog(dept,item,"调整部门"));
			});
			boolean ret = tmCustomerService.updateBatchById(tmCustomerList);
			//管户关系日志记录
			tmCustomerLogService.saveBatch(tmCustomerLogList);
			return R.status(ret);
		}else{
			return R.status(false);
		}
	}

	/**
	 * 删除 客户信息
	 * 仅修改del_flag状态为1 废弃，不物理删除
	 */
	@PostMapping("/changeTag")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "逻辑删除", notes = "传入ids")
	@Transactional(rollbackFor = Exception.class)
	public R changeTag(@ApiParam(value = "主键集合", required = true)@RequestBody TmCustomerVO tmCustomerVO) {
		List<Long> idList = Func.toLongList(tmCustomerVO.getIds());
		List<TmCustomer> tmCustomerList = tmCustomerService.listByIds(idList);
		tmCustomerList.forEach(item->{
			item.setAgeTag(tmCustomerVO.getAgeTag());
			item.setProductTag(tmCustomerVO.getProductTag());
			item.setLevelTag(tmCustomerVO.getLevelTag());
		});
		tmCustomerService.updateBatchById(tmCustomerList);
		return R.status(true);
	}

	private R addTag(List<Long> idList, @RequestBody @ApiParam(value = "主键集合", required = true) TmCustomerTagVO tmCustomerTagVO) {
		List<TmCustomerTag> tmCustomerTagList = new ArrayList<>();
		idList.forEach(custId->{
			List<String> tagList = Func.toStrList("9,9",tmCustomerTagVO.getTags());
			tagList.forEach(tag->{
				TmCustomerTag tmCustomerTag = new TmCustomerTag();
				tmCustomerTag.setLevel(tmCustomerTagVO.getLevel());
				tmCustomerTag.setCustomerId(custId);
				tmCustomerTag.setName(tag);
				if (!"0".equals(tmCustomerTagVO.getLevel())){
					tmCustomerTag.setDeptId(tmCustomerTagVO.getDeptId());
					tmCustomerTag.setDeptName(tmCustomerTagVO.getDeptName());
				}
				tmCustomerTagList.add(tmCustomerTag);
			});
		});
		boolean ret = tmCustomerTagService.saveBatch(tmCustomerTagList);
		return R.status(ret);
	}

	/**
	 * 详情
	 */
	@GetMapping("/isCustomer")
	@ApiOperationSupport(order = 1)
	@ApiOperation(value = "详情", notes = "tmCustomer")
	public R isCustomer(TmCustomer tmCustomer) {
		if(MyStringUtil.isNotEmpty(tmCustomer.getCustomerTel())){
			try {
				tmCustomer.setCustomerTel(AESUtil.encrypt(tmCustomer.getCustomerTel(),BankConstants.KEY));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		List list = tmCustomerService.list(new LambdaQueryWrapper<TmCustomer>().eq(TmCustomer::getCustomerTel,tmCustomer.getCustomerTel()));
		List listBk = tmCustomerService.list(new LambdaQueryWrapper<TmCustomer>().eq(TmCustomer::getCustomerTelBack,tmCustomer.getCustomerTel()));
		if (list.size()>0||listBk.size()>0){
			return R.data(true);
		}else{
			return R.data(false);
		}
	}

	/**
	 * 分页 客户信息
	 */
	@GetMapping("/noTaskList")
	@ApiOperationSupport(order = 2)
	@ApiOperation(value = "分页", notes = "传入tmCustomer")
	public R<IPage<TmCustomer>> noTaskList(TmCustomerVO tmCustomer, Query query) throws Exception {
		if(MyStringUtil.isNotEmpty(tmCustomer.getCustomerName())){
			tmCustomer.setCustomerName(AESUtil.encrypt(tmCustomer.getCustomerName(),BankConstants.KEY));
		}
		if (MyStringUtil.isNotEmpty(tmCustomer.getCustomerTel())){
			tmCustomer.setCustomerTel(AESUtil.encrypt(tmCustomer.getCustomerTel(),BankConstants.KEY));
		}

		IPage<TmCustomer> pages = tmCustomerService.noTaskTmCustomerPage(Condition.getPage(query), tmCustomer);
		pages.getRecords().forEach(item->{
			try {
				if (MyStringUtil.isNotEmpty(item.getCustomerName())){
					item.setCustomerName(AESUtil.decrypt(item.getCustomerName(),BankConstants.KEY));
				}
				if (MyStringUtil.isNotEmpty(item.getCustomerTel())){
					item.setCustomerTel(AESUtil.decrypt(item.getCustomerTel(),BankConstants.KEY));
				}
			} catch (Exception e) {
				log.warn("Exception",e);
			}
		});
		return R.data(pages);
	}

	@PostMapping("/linkAll")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "任务关联所有客户", notes = "传入ids")
	@Transactional(rollbackFor = Exception.class)
	public R linkAll(@ApiParam(value = "主键集合", required = true)@RequestBody TmCustomerVO tmCustomer) {
		Query query = new Query();
		query.setSize(5000);
		query.setCurrent(1);
		IPage<TmCustomer> pages = tmCustomerService.noTaskTmCustomerPage(Condition.getPage(query), tmCustomer);
		boolean ret = makeTask(pages.getRecords(),tmCustomer.getTaskId());
		return R.status(ret);
	}

	@PostMapping("/link")
	@ApiOperationSupport(order = 7)
	@ApiOperation(value = "任务关联客户", notes = "传入ids")
	public R link(@ApiParam(value = "主键集合", required = true) @RequestBody TmCustomerVO tmCustomer) {
		List<TmCustomer> tmCustomerList = tmCustomerService.listByIds(Func.toLongList(tmCustomer.getIds()));
		boolean ret = makeTask(tmCustomerList,tmCustomer.getTaskId());
		return R.status(ret);
	}

	private boolean makeTask(List<TmCustomer> tmCustomerList,Long taskId){
		TmVisitTask tmVisitTask = tmVisitTaskService.getById(taskId);
		List<TmVisitTaskCustomer> addTaskCustomer = new ArrayList<>();
		for (TmCustomer temp : tmCustomerList) {
			TmVisitTaskCustomer  taskCustomer=new TmVisitTaskCustomer();
			taskCustomer.setTaskId(tmVisitTask.getId());
			taskCustomer.setTaskCode(tmVisitTask.getTaskCode());
			taskCustomer.setDeptId(Long.valueOf(temp.getDeptId()));
			taskCustomer.setDeptName(temp.getDeptName());
			taskCustomer.setCustMgr(temp.getCustMgr());
			taskCustomer.setCustMgrName(temp.getCustMgrName());
			taskCustomer.setCustomerCode(temp.getCustomerCode());
			taskCustomer.setCustomerPhone(temp.getCustomerTel());
			taskCustomer.setSex(temp.getSex());
			taskCustomer.setVisitStatus("0");
			taskCustomer.setEx2(EX1_TYPE_BUSINESS);
			addTaskCustomer.add(taskCustomer);
		};
		boolean ret = tmVisitTaskCustomerService.saveBatch(addTaskCustomer);
		return ret;
	}
}
